package tms.util.security;

import tms.business.login.LoginService;
import tms.model.login.UserEntity;
import tms.util.constants.CookieParameter;
import tms.util.jsf.FacesContextManager;

import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.inject.Named;
import java.io.Serializable;

@Named
@SessionScoped
public class AppSecurityManager implements Serializable {
    private final static int AGE = 14 * 24 * 3600 * 1000;

    @EJB
    LoginService loginService;
    @Inject
    FacesContextManager facesContextManager;

    private UserEntity user;

    public boolean isLoggedIn() {
        return user != null;
    }

    public void login(String name, String password, boolean remember) {
        this.user = loginService.login(name, password);
        if (remember) {
            facesContextManager.addCookie(CookieParameter.UID, String.valueOf(user.getId()), AGE);
            facesContextManager.addCookie(CookieParameter.HASH, normalizeHash(loginService.buildHash(user.getName() + user.getPassword())), AGE);
        }
    }

    public void logout() {
        user = null;
        facesContextManager.addCookie(CookieParameter.UID, "", 0);
        facesContextManager.addCookie(CookieParameter.HASH, "", 0);
    }

    public boolean checkRemembered() {
        boolean retVal = false;

        String userIdCookie = facesContextManager.getCookieParameter(CookieParameter.UID);
        String hashCookie = facesContextManager.getCookieParameter(CookieParameter.HASH);
        if (!userIdCookie.isEmpty() && !hashCookie.isEmpty()) {
            try {
                Integer userId = Integer.parseInt(userIdCookie);
                UserEntity possibleUser = loginService.findUser(userId);
                if (possibleUser != null && hashCookie.equals(normalizeHash(loginService.buildHash(possibleUser.getName() + possibleUser.getPassword())))) {
                    user = possibleUser;
                    facesContextManager.addCookie(CookieParameter.UID, userIdCookie, AGE);
                    facesContextManager.addCookie(CookieParameter.HASH, hashCookie, AGE);
                    retVal = true;
                }
            } catch (NumberFormatException e) {}
        }

        return retVal;
    }

    public UserEntity getUser() {
        return user;
    }

    /**
     * Method replaces symbols denied in cookies.
     *
     * @param hash - initial hash
     * @return normalized hash
     */
    private String normalizeHash(String hash) {
        return hash.
                replaceAll("\\s", "").
                replaceAll("\\(", "").
                replaceAll("\\)", "").
                replaceAll("\\[", "").
                replaceAll("\\]", "").
                replaceAll("\\{", "").
                replaceAll("\\}", "").
                replaceAll("=", "").
                replaceAll(",", "").
                replaceAll("'", "").
                replaceAll("\\\\", "").
                replaceAll("\\?", "").
                replaceAll(",", "").
                replaceAll("@", "").
                replaceAll(":", "").
                replaceAll(";", "").
                replaceAll("\"", "");
    }
}
